#ifndef _TASK_H
#define _TASK_H
#include <mm.h>
#include <list.h>
#include <asm/kbuid.h>
#include <pt_regs.h>
#include <offect.h>
#define NR_TASK 128

#define SET_LINKS(p) do { \
	(p)->next_task = &init_task; \
	(p)->prev_task = init_task.prev_task; \
	init_task.prev_task->next_task = (p); \
	init_task.prev_task = (p); \
} while (0)

typedef struct cpu_context
{
   unsigned long x19;
   unsigned long x20;
   unsigned long x21;
   unsigned long x22;
   unsigned long x23;
   unsigned long x24;
   unsigned long x25;
   unsigned long x26;
   unsigned long x27;
   unsigned long x28;
   unsigned long fp;
   unsigned long sp;
   unsigned long pc;
} cpu_context;

typedef enum task_state{
    TASK_RUNNING = 0,
    TASK_INTERRUPTIBLE = 1,
    TASK_UNINTERRRUPTIBLE = 2,
    TASK_ZOMBIE = 3,
    TASK_STOPPED = 4,
} task_state;

typedef enum task_flags{
    PF_KTHREAD = 1 << 0,
} task_flags;

typedef struct task_struct
{
    task_state state;
    task_flags flags;
    int pid;
    cpu_context cpu_context;
    struct list_head run_list;
    int counter;
    int priority;
    int need_resched;
    int preempt_count;
    struct task_struct *next_task;
    struct task_struct *prev_task;
} task_struct;

typedef union task_union{
    task_struct task;
    unsigned long stack[THREAD_SIZE/sizeof(long)];
} task_union;


extern task_union init_task_union;

#define __init_task_data __attribute__((__section__(".data.init_task")))
#define init_task (init_task_union.task)
extern task_struct *g_task[];

extern void ret_from_fork(void);
static int find_empty_task(void);
int do_fork(unsigned long clone_flags, unsigned long fn, unsigned long arg);
task_struct* switch_to(task_struct *next, task_struct *prev);

#endif // !_TASK_H

